#pragma once
#include"Triangle3D.h"
#include"Quadrangle3D.h"
#include"BinaryTreeNode.h"
#include"Projection.h"
#include"Material.h"
#include"Light.h"
#include"Surface.h"
#include<vector>
using namespace std;

typedef BinaryTreeNode<Triangle3D>* BSPTree;
typedef BinaryTreeNode<Triangle3D> _BSPNode;


class Blanking
{
public:
	Blanking();
	~Blanking();
	static void PainterAlgorithm(Triangle3D Ts[], int n, Projection pro);
	static void PainterAlgorithm(Triangle3D Ts[], int n, Projection pro, Material material, Light light);
	static void ZBuffer(Triangle3D Ts[], int n, Projection pro, bool isSingleColor = false);
	static void ZBuffer(Triangle3D Ts[], int n, Projection pro, Material material, Light light, int mode = 0, int method = 0);
	static void ZBuffer(Quadrangle3D Qs[], int n, Projection pro);
	static void ZBuffer(Quadrangle3D Qs[], int n, Projection pro, Material material, Light light, int mode = 0, int method = 0);
	static void ZBuffer(vector<Surface*> objs, Projection pro, Light light, int method = 0);
	static void Wireframe(Triangle3D Ts[], int n, Projection pro, int mode = 0);
private:
	static BSPTree BuildBSPTree(Triangle3D Ts[], int n);
	static void AddTriangle(BSPTree& tree,Triangle3D& T);
	static double F(Vector3 p, Vector3 a, Vector3 b, Vector3 c);
	static P3D  Intersect(P3D p1, P3D p2, Triangle3D T);
	static void Draw(BSPTree& tree,Projection pro);
	static void Draw(BSPTree& tree, Projection pro, Material material, Light light);

	template<class T>
	static void Swap(T& t1, T& t2);
};

template<class T>
inline void Blanking::Swap(T& t1, T& t2)
{
	T tem = t1;
	t1 = t2;
	t2 = tem;
}
